package com.hliushi.demo.resolver;

import com.hliushi.demo.anno.CurrentUser;
import com.hliushi.demo.entity.User;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 动态为Controller方法注入当前登录用户对象
 *
 * @author llhuang10
 * @date 2021/8/25 22:05
 */
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {


    /**
     * 控制resolveArgument方法的执行, 判断依据是否有@CurrentUser注解
     *
     * @param parameter
     * @return true 方法执行, false 则不执行
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 判断当前Controller方法中的参数类型是否自己定义的User, 同时形参上是否加入@CurrentUser注解
        if (parameter.getParameterType().equals(User.class) &&
                parameter.hasParameterAnnotation(CurrentUser.class)) {
            return true;
        }
        return false;


    }


    /**
     * 当supportsParameter方法返回true时执行此方法
     *
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 动态获取当前登录用户信息
        // 由于没有引入 jwt模块 和 的登录模块, 所以这里简单处理

        // 此处直接模拟了一些User对象, 实际项目中可能需要从请求头获取登录用户的令牌进行解析
        // 最终封装成User对象返回即可, 这样在Controller的方法形参就可以直接引用到User对象了
        return new User(1001, "llhuang10", 12);
    }
}
